# application/services/system/auth.py
from application.extensions.logging import system_logger
from application.mapper.system.user import UserMapper
from werkzeug.security import check_password_hash
import jwt
from datetime import datetime, timedelta
from application.config import BaseConfig
import bcrypt


class AuthService:
    """认证服务层"""

    @staticmethod
    def login(username: str, password: str) -> dict:
        """
        用户登录认证
        :param username: 用户名
        :param password: 密码
        :return: 认证结果
        """
        # 1. 验证用户是否存在
        user = UserMapper.get_user_by_username(username)
        if not user:
            raise Exception("没有此用户")

        # 2. 检查用户状态（假设status='0'表示正常）
        if getattr(user, "status", "1") != "0":
            raise Exception("用户账户已被停用")

        # 3. 验证密码
        password_hash = getattr(user, "password", None)
        if not password_hash:
            system_logger.error(f"用户 {username} 的密码字段不存在")
            raise Exception("用户数据异常")

        # 使用 bcrypt 验证密码
        if not AuthService.check_password(password, password_hash):
            raise Exception("密码错误")

        # 4. 生成JWT token
        payload = {
            "loginType": "login",
            "loginId": f"sys_user:{user.user_id}",
            "userId": user.user_id,
            "userName": user.user_name,
            "tenantId": getattr(user, "tenant_id", ""),
            "deptId": getattr(user, "dept_id", ""),
            "exp": datetime.utcnow()
            + timedelta(seconds=BaseConfig.JWT_ACCESS_TOKEN_EXPIRES or 604800),
        }

        access_token = jwt.encode(payload, BaseConfig.SECRET_KEY, algorithm="HS256")

        return {
            "access_token": access_token,
            "expire_in": BaseConfig.JWT_ACCESS_TOKEN_EXPIRES or 604800,
        }

    @staticmethod
    def verify_token(token: str) -> dict:
        """
        验证JWT token
        :param token: JWT token
        :return: 验证结果
        """
        try:
            # 处理Bearer前缀
            if token.startswith("Bearer "):
                token = token[7:]

            # 解码token
            payload = jwt.decode(token, BaseConfig.SECRET_KEY, algorithms=["HS256"])
            user_id = payload.get("userId")

            if not user_id:
                return {"code": 401, "msg": "无效的token"}

            # 验证用户仍然有效
            user = UserMapper.get_user_by_id(user_id)
            if not user or getattr(user, "status", "1") != "0":
                return {"code": 401, "msg": "用户不存在或已被禁用"}

            return {
                "code": 200,
                "msg": "token有效",
                "data": {
                    "user_id": user_id,
                    "user_name": payload.get("userName"),
                    "tenant_id": payload.get("tenantId"),
                    "dept_id": payload.get("deptId"),
                },
            }

        except jwt.ExpiredSignatureError:
            return {"code": 401, "msg": "token已过期"}
        except jwt.InvalidTokenError:
            return {"code": 401, "msg": "无效的token"}
        except Exception as e:
            system_logger.error(f"token验证失败: {str(e)}")
            return {"code": 500, "msg": "验证过程发生错误"}

    @staticmethod
    def generate_bcrypt_hash(password: str) -> str:
        """使用 bcrypt 生成密码哈希"""
        password_bytes = password.encode("utf-8")
        hashed = bcrypt.hashpw(password_bytes, bcrypt.gensalt())
        return hashed.decode("utf-8")

    @staticmethod
    def check_password(input_password: str, hashed_password: str) -> bool:
        """
        使用 bcrypt 验证密码
        :param input_password: 用户输入的密码
        :param hashed_password: 数据库中存储的哈希密码
        :return: 密码是否正确
        """
        try:
            # 将密码和哈希值都转换为字节
            password_bytes = input_password.encode("utf-8")
            hashed_bytes = hashed_password.encode("utf-8")
            # 使用 bcrypt 验证密码
            return bcrypt.checkpw(password_bytes, hashed_bytes)
        except Exception as e:
            system_logger.error(f"bcrypt密码验证失败: {str(e)}")
            return False
